package com.kaoshi.myweb.common.web.lister;
import java.io.FileNotFoundException;
import java.lang.reflect.Method;
import java.net.URL;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.StaticLoggerBinder;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.SystemPropertyUtils;
import org.springframework.web.util.WebUtils;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.selector.ContextSelector;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.classic.util.ContextSelectorStaticBinder;
import ch.qos.logback.core.joran.spi.JoranException;
/**
 * <p>   配置文件示例
  * <p> <listener>
 * <p>      <listener-class>
  * <p>         com.kaoshi.myweb.common.web.lister.LogbackConfigListener
 * <p>      </listener-class>
 * <p>  </listener>
  *<p>  <context-param>
  *<p>      <param-name>logbackConfigLocation</param-name>
  *<p>      <param-value>WEB-INF/logback.xml 或  classpath:logback.xml</param-value>
 * <p>  </context-param>
 * @version 1.0
 * 参考自：https://github.com/qos-ch/logback-extensions
 */
public class LogbackConfigListener implements ServletContextListener {
    private static final Logger logger = LoggerFactory.getLogger(LogbackConfigListener.class);
   
    private static final String CONFIG_LOCATION = "logbackConfigLocation";
    @Override
    public void contextInitialized(ServletContextEvent event) {
        //从web.xml中加载指定文件名的日志配置文件
        String logbackConfigLocation = event.getServletContext().getInitParameter(CONFIG_LOCATION);
        
        logbackConfigLocation = SystemPropertyUtils.resolvePlaceholders(logbackConfigLocation);

        try {
        	
            URL url = ResourceUtils.getURL(logbackConfigLocation);
            LoggerContext loggerContext = (LoggerContext)StaticLoggerBinder.getSingleton().getLoggerFactory();

            // in the current version logback automatically configures at startup the context, so we have to reset it
            loggerContext.reset();

            // reinitialize the logger context.  calling this method allows configuration through groovy or xml
            new ContextInitializer(loggerContext).configureByResource(url);
            
            logger.info("loading slf4j configure file from " + logbackConfigLocation );
            
        }
        catch (FileNotFoundException e) {
       	 	throw new IllegalArgumentException("Invalid 'logbackConfigLocation' parameter: " + e.getMessage());
		}
        catch (JoranException e) {
        	 throw new RuntimeException("Unexpected error while configuring logback", e);
        } 
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent servletContext) {
    	//Uninstall the SLF4J java.util.logging bridge *before* shutting down the Logback framework.
        try {
            Class<?> julBridge = ClassUtils.forName("org.slf4j.bridge.SLF4JBridgeHandler", ClassUtils.getDefaultClassLoader());
            Method uninstall = ReflectionUtils.findMethod(julBridge, "uninstall");
            if (uninstall != null) {
                ReflectionUtils.invokeMethod(uninstall, null);
            }
        } catch (ClassNotFoundException ignored) {
            //No need to shutdown the java.util.logging bridge. If it's not on the classpath, it wasn't started either.
        }

        try {
        	 ContextSelector selector = ContextSelectorStaticBinder.getSingleton().getContextSelector();
             LoggerContext loggerContext = selector.getLoggerContext();
             String loggerContextName = loggerContext.getName();
             LoggerContext context = selector.detachLoggerContext(loggerContextName);
             context.reset();
        } finally {
        	
        }
    }
    
}